package com.service.impl;

import com.alibaba.dubbo.config.annotation.Service;
import com.constant.MessageConstant;
import com.exception.CustomException;
import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import com.mapper.*;
import com.pageResult.PageResult;
import com.pojo.*;
import com.query.QueryPageBean;
import com.service.SetmealService;
import com.utils.QiNiuUtils;
import freemarker.template.Configuration;
import freemarker.template.Template;
import freemarker.template.TemplateException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.servlet.view.freemarker.FreeMarkerConfig;

import java.io.*;
import java.util.HashMap;
import java.util.List;
import java.util.Map;


@Service(interfaceClass = SetmealService.class)
public class SetmealServiceImpl implements SetmealService {

    @Autowired
    private SetmealMapper setmealMapper;

    @Autowired
    private FreeMarkerConfig freeMarkerConfig;//注入FreeMarkerConfig

    @Value("${out_put_path}")
    private String out_put_path;//引入FreeMarker配置类中的输出路径

    //生成套餐列表、套餐具体详情静态页面
    private void  generateMobileStaticHtml(){
        System.out.println("生成静态页面.....");

        //2.准备套餐列表页面的数据
        List<Setmeal> setMealList=setmealMapper.selectByExample(null);

        //b.1 需要生成套餐列表页面（一个）
        generateSetMealListHtml(setMealList);
        //b.2 需要生成套餐详情页面(多个)
        generateSetMealDetailsHtml(setMealList);

    }

    //b.1 生成套餐列表静态页面
    private void generateSetMealListHtml(List<Setmeal> setMealList){
        System.out.println("生成套餐列表静态页面.....");

        setMealList.forEach(s->{
            s.setImg(QiNiuUtils.DOMAIN+s.getImg());
        });

        Map map=new HashMap();
        map.put("setmealList",setMealList);

        generateHtml("mobile_setmeal.ftl",out_put_path+"mobile_setmeal.html",map);

    }

    //b.2 生成套餐详情页面(多个)
    private void generateSetMealDetailsHtml(List<Setmeal> setMealList){
        System.out.println("生成套餐详情页面(多个).....");
        //尝试自己补完代码
        setMealList.forEach(s->{
            Setmeal setmeal = setmealMapper.queryDetailById(s.getId());
            setmeal.setImg(QiNiuUtils.DOMAIN+setmeal.getImg());

            Map map=new HashMap();
            map.put("setmeal",setmeal);
            generateHtml("mobile_setmeal_detail.ftl",out_put_path+"mobile_setmeal_detail_"+setmeal.getId()+".html",map);
        });
    }

    //封装FreeMarker的工具类
    private void generateHtml(String templateName, String outputPath, Map<String,Object> map){
        //1.创建配置类
        Configuration configuration=freeMarkerConfig.getConfiguration();
        System.out.println(outputPath+"====================");
        //2.加载模板
        Template template = null;
        BufferedWriter bw=null;
        try {
            template = configuration.getTemplate(templateName);
            //3.创建数据模型

            //4.创输出文件路径对象
            bw=new BufferedWriter(new OutputStreamWriter(new FileOutputStream(outputPath),"utf-8"));
            //5.将数据填充到模板
            template.process(map, bw);
            //6.刷新缓冲流
            bw.flush();

        } catch (IOException e) {
            e.printStackTrace();
        } catch (TemplateException e) {
            e.printStackTrace();
        } finally {
            //7.关闭Writer对象
            try {
                bw.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }


    @Override
    public List<Map<String, Object>> getSetmealReport() {
        return setmealMapper.getSetmealReport();
    }

    @Override
    public Setmeal queryDetailById(Integer id) {
        /**
         * java代码实现
         * */
        /*//1.根据id查询套餐
        Setmeal setmeal = setmealMapper.selectByPrimaryKey(id);
        //2.根据套餐id查询检查组
        List<CheckGroup> checkGroups = setmealMapper.queryBySetMealId(setmeal.getId());
        //3.把检查组数据封装到套餐属性上
        setmeal.setCheckGroup(checkGroups);
        for (CheckGroup cg:checkGroups) {
            //4..根据检查组id查询检查项
            List<CheckItem> checkItems = setmealMapper.queryByCheckGroupId(cg.getId());
            //5.把检查项数据封装到检查组属性上
            cg.setCheckItems(checkItems);
        }
        return setmeal;*/
        /**
         * 嵌套查询
         * */
        //return setmealMapper.queryDetailByIdTwo(id);
        /**
         * 联合查询
         * */
        return setmealMapper.queryDetailById(id);
    }

    //查询所有带分页+条件
    @Override
    public PageResult selectByQueryString(QueryPageBean queryPageBean) {
        PageHelper.startPage(queryPageBean.getCurrentPage(),queryPageBean.getPageSize(),true);
        Page<Setmeal> page = setmealMapper.selectByQueryString(queryPageBean.getQueryString());
        return new PageResult(page.getTotal(),page.getResult());
    }

    //添加
    @Transactional
    @Override
    public void add(Setmeal setmeal, Integer[] checkgroupIds) throws CustomException {
        //1.先添加套餐表数据
        setmealMapper.insertSelective(setmeal);
        //2.插入数据到第三表
        if(checkgroupIds!=null && checkgroupIds.length>0){
            setmealMapper.addSetmealAndCheckGroup(setmeal.getId(), checkgroupIds);
            //调用生成静态页面
            generateMobileStaticHtml();
        }else {
            throw new CustomException("至少选择一个套餐！");
        }

    }
    // //根据id查询数据
    @Override
    public Setmeal queryById(Integer SetmealId) {
        return setmealMapper.selectByPrimaryKey(SetmealId);
    }
    ////查询该套餐对应的检查组id
    @Override
    public Integer[] queryByCheckGroup(Integer SetmealId) {
        return setmealMapper.queryByCheckGroup(SetmealId);
    }
    //修改
    @Transactional
    @Override
    public void update(Setmeal setmeal, Integer[] checkgroupIds) throws CustomException {
        //1.先修改套餐表数据
        setmealMapper.updateByPrimaryKeySelective(setmeal);

        if(checkgroupIds!=null && checkgroupIds.length>0){
            //2.先删除第三方表该套餐数据
            setmealMapper.deleteBySetMeal(setmeal.getId());
            //3.在重新插入数据到第三表
            setmealMapper.addSetmealAndCheckGroup(setmeal.getId(),checkgroupIds);

            //调用生成静态页面
            generateMobileStaticHtml();
        }else {
            throw new CustomException("至少选择一个套餐！");
        }

    }
    //删除
    @Transactional
    @Override
    public void delete(Integer SetmealId) throws CustomException {

        File file = new File(out_put_path + "mobile_setmeal_detail_" + SetmealId + ".html");
        file.delete();

        //删除之前先看看订单里面有没有引用该套餐
        Integer count = setmealMapper.isUseInOrder(SetmealId);
        if(count>0){
            //引用了不能删除，抛出异常
            throw new CustomException(MessageConstant.SETMEAL_IS_USE);
        }
        //没有引用先解除和检查组的关系
        Integer countt = setmealMapper.isUseInSemeal(SetmealId);
        if(countt>0){//先判断该套餐有没有和检查组关系
            setmealMapper.deleteBySetMeal(SetmealId);
        }
        //在删除数据
        setmealMapper.deleteByPrimaryKey(SetmealId);

        //调用生成静态页面
        generateMobileStaticHtml();

    }

    @Override
    public List<Setmeal> findAll() {
        return setmealMapper.selectByExample(null);
    }
}
